package com.intellif.mozping;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * @author by mozping
 * @Classname WatchZookeeper
 * @Description TODO
 * @Date 2019/6/14 16:48
 */
public class WatchZookeeper {

    private static final String CONNECT_STRING = "192.168.13.53";
    private static final int CONNECT_TIME_OUT = 5000;
    private static CountDownLatch countDownLatch = new CountDownLatch(1);
    private static final Logger LOG = LoggerFactory.getLogger(WatchZookeeper.class);
    private static ZooKeeper zookeeper;
    private static Stat stat = new Stat();

    private static final String PARENT_PATH = "/node1";
    private static final String CHILD_PATH = "/node2";

    private static final String VALUE = "123";
    private static final String NEW_VALUE = "1234";

    public static void main(String[] args) throws Exception {
        //1.创建zk客户端，并且注册一个监听器
        LOG.info("准备建立连接...");
        zookeeper = new ZooKeeper(CONNECT_STRING, CONNECT_TIME_OUT, new MyWatch());
        countDownLatch.await();
        TimeUnit.SECONDS.sleep(1);

        //2.创建节点
        LOG.info("准备创建节点...");
        String result = zookeeper.create(PARENT_PATH, VALUE.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        TimeUnit.SECONDS.sleep(2);

        //3.修改节点数据
        LOG.info("准备修改节点数据...");
        zookeeper.getData(PARENT_PATH, new MyWatch(), stat);
        zookeeper.setData(PARENT_PATH, NEW_VALUE.getBytes(), -1);
        TimeUnit.SECONDS.sleep(2);

        //4.查询节点
        LOG.info("准备查询节点数据...");
        byte[] data = zookeeper.getData(PARENT_PATH, false, stat);
        LOG.info("查询数据是:" + new String(data));
        TimeUnit.SECONDS.sleep(2);

        //5.创建子节点
        LOG.info("准备创建子节点...");
        Stat stat = zookeeper.exists(PARENT_PATH + CHILD_PATH, true);
        //表示节点不存在
        if (stat == null) {
            zookeeper.create(PARENT_PATH + CHILD_PATH, VALUE.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
        TimeUnit.SECONDS.sleep(2);

        //6.修改子节点数据
        LOG.info("准备修改子节点数据...");
        zookeeper.setData(PARENT_PATH+CHILD_PATH, NEW_VALUE.getBytes(), -1);
        TimeUnit.SECONDS.sleep(2);


        //7.删除节点
        LOG.info("准备删除子节点...");
        zookeeper.delete(PARENT_PATH + CHILD_PATH, -1);
        TimeUnit.SECONDS.sleep(2);

        LOG.info("准备删除父节点...");
        zookeeper.delete(PARENT_PATH, -1);
        TimeUnit.SECONDS.sleep(1);

    }


    /**
     * zookeeper的Watcher监听器
     */
    static class MyWatch implements Watcher {

        public void process(WatchedEvent watchedEvent) {
            //如果当前的连接状态是连接成功的，那么通过计数器去控制
            if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
                if (Event.EventType.None == watchedEvent.getType() && null == watchedEvent.getPath()) {
                    countDownLatch.countDown();
                    LOG.info("监听到创建连接成功, " + watchedEvent.getState() + "-->" + watchedEvent.getType());
                } else if (watchedEvent.getType() == Event.EventType.NodeDataChanged) {
                    try {
                        LOG.info("监听到节点数据变化，路径：" + watchedEvent.getPath() + "->数据值：" +
                                new String(zookeeper.getData(watchedEvent.getPath(), true, stat)));
                    } catch (KeeperException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //子节点的数据变化会触发
                } else if (watchedEvent.getType() == Event.EventType.NodeChildrenChanged) {
                    try {
                        LOG.info("监听到创建子节点数据变化，路径：" + watchedEvent.getPath() + "->数据值：" +
                                zookeeper.getData(watchedEvent.getPath(), true, stat));
                    } catch (KeeperException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //创建子节点的时候会触发
                } else if (watchedEvent.getType() == Event.EventType.NodeCreated) {
                    try {
                        LOG.info("监听到创建子节点，路径：" + watchedEvent.getPath() + "->节点的值：" + new String(
                                zookeeper.getData(watchedEvent.getPath(), true, stat)));
                    } catch (KeeperException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else if (watchedEvent.getType() == Event.EventType.NodeDeleted) {//子节点删除会触发
                    LOG.info("监听到节点删除， 路径：" + watchedEvent.getPath());
                }
            }
        }
    }
}